package au.org.htd.youslide.ppt;

import java.io.IOException;
import java.io.OutputStream;
import java.util.StringTokenizer;
import java.util.logging.Logger;

import au.org.htd.youslide.Background;
import au.org.htd.youslide.SongProject;
import au.org.htd.youslide.Util;

import com.lowagie.text.Document;
import com.lowagie.text.Font;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfWriter;

public class XMLSong implements Song {
   private static final Logger log = Logger.getLogger(XMLSong.class.getName());

   String content;
   String chineseContent;
   String englishContent;
   SongProject song;
   String footer;

   Font TitleEnglish = new Font(Font.COURIER, 22, Font.BOLD);
   Font FontEnglish = new Font(Font.COURIER, 14, Font.NORMAL);
   BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",
         BaseFont.NOT_EMBEDDED);
   Font TitleChinese = new Font(bfChinese, 22, Font.BOLD);
   Font FontChinese = new Font(bfChinese, 14, Font.NORMAL);

   public XMLSong(SongProject song) throws Exception {
      this.song = song;
      Background background = new Background(song.getPm()).get(song
            .getBackgroundId());
      byte[] titleData = background.getBackground();

      content = Util.getXMLTemplate();
      String dataTags = "<pkg:binaryData></pkg:binaryData>";
      content = Util.insert(content, titleData, content.indexOf(dataTags) + 16);
      content = Util.insert(content, Util.getBg(), content
            .lastIndexOf(dataTags) + 16);

      content = content.replace("English Name", song.getEnglishName());
      content = content.replace("Chinese Name", song.getChineseName());
      content = content.replace("chineseFont", "汉鼎简中楷");

      DisplayText name = song.getName();
      footer = name.getEnglishText()
            + (name.getEnglishText().length() > 0 ? " / " : "")
            + name.getChineseText() + " - Page ";
   }

   private void addSlide(int id, String top, String bottom, String footer,
         String template) {
      String anchor = "<Relationship Id=\"rId" + (id + 6)
            + "\" Type=\"http://schemas.openxmlformats.org/officeDocument/"
            + "2006/relationships/slide\" Target=\"slides/slide" + (id - 1)
            + ".xml\"/>";
      content = Util.insert(content, "<Relationship Id=\"rId" + (id + 7)
            + "\" Type=\"http://schemas.openxmlformats.org/officeDocument/"
            + "2006/relationships/slide\" Target=\"slides/slide" + id
            + ".xml\"/>", content.indexOf(anchor) + anchor.length());
      anchor = "<p:sldId id=\"" + (id + 254) + "\" r:id=\"rId" + (id + 6)
            + "\"/>";
      content = Util.insert(content, "<p:sldId id=\"" + (id + 255)
            + "\" r:id=\"rId" + (id + 7) + "\"/>", content.indexOf(anchor)
            + anchor.length());

      StringTokenizer tok = new StringTokenizer(top.trim(), (char) 13 + "");
      int englishSize = DisplayText.getEnglishFontSize(tok.countTokens());
      tok = new StringTokenizer(bottom.trim(), (char) 13 + "");
      int chineseSize = DisplayText.getChineseFontSize(tok.countTokens());

      content = Util.insert(content, template, content
            .lastIndexOf("</pkg:package>"));
      content = content.replace("slideId", "" + id);
      content = content.replace("notesId", "" + (id - 1));
      content = content.replace("englishLyrics", top.trim());
      content = content.replace("chineseLyrics", bottom.trim());
      content = content.replace("englishSize", "" + englishSize);
      content = content.replace("chineseSize", "" + chineseSize);
      content = content.replace("footer", footer);
      content = content.replace("chineseFont", "汉鼎简中楷");
   }

   @Override
   public void writeChineseOnly(OutputStream o) throws IOException {
      DisplayText lyrics = song.getLyrics();
      StringTokenizer chineseTok = Util.getTok(lyrics.getChineseText());

      int page = 1;
      int pages = new Double(chineseTok.countTokens() / 2 + 1).intValue();
      for (int slideIndex = 2; chineseTok.hasMoreTokens(); slideIndex++) {
         String bottom = chineseTok.nextToken();
         if (chineseTok.hasMoreElements()) {
            bottom += chineseTok.nextToken();
         }
         addSlide(slideIndex, "", bottom, footer + (++page) + " of " + pages,
               Util.getChineseTemplate());
      }
      // new OutputStreamWriter(o).write(content);
   }

   @Override
   public void writeEnglishOnly(OutputStream o) throws IOException {
      DisplayText lyrics = song.getLyrics();
      StringTokenizer englishTok = Util.getTok(lyrics.getEnglishText());

      int page = 1;
      int pages = new Double(englishTok.countTokens() / 2 + 1).intValue();
      for (int slideIndex = 2; englishTok.hasMoreTokens(); slideIndex++) {
         String top = englishTok.nextToken();
         if (englishTok.hasMoreElements()) {
            top += englishTok.nextToken();
         }

         addSlide(slideIndex, top, "", footer + (++page) + " of " + pages, Util
               .getEnglishTemplate());
      }
      // new OutputStreamWriter(o).write(content);
   }

   @Override
   public void writeSlides(OutputStream o) throws IOException {
      DisplayText lyrics = song.getLyrics();
      StringTokenizer englishTok = Util.getTok(lyrics.getEnglishText());
      StringTokenizer chineseTok = Util.getTok(lyrics.getChineseText());

      int page = 1;
      int pages = englishTok.countTokens() + 1;
      for (int slideIndex = 2; englishTok.hasMoreTokens()
            || chineseTok.hasMoreTokens(); slideIndex++) {
         String top, bottom;
         if (englishTok.hasMoreTokens()) {
            top = englishTok.nextToken();
            if (chineseTok.hasMoreElements()) {
               bottom = chineseTok.nextToken();
            } else if (englishTok.hasMoreTokens()) {
               bottom = englishTok.nextToken();
            } else {
               bottom = "";
            }
         } else {
            top = chineseTok.nextToken();
            if (chineseTok.hasMoreElements()) {
               bottom = chineseTok.nextToken();
            } else {
               bottom = "";
            }
         }

         addSlide(slideIndex, top, bottom, footer + (++page) + " of " + pages,
               Util.getXMLSlideTemplate());
      }
      // new OutputStreamWriter(o).write(content);
   }

   public String getContent() {
      return content;
   }

   @Override
   public String getContentType() {
      return "text/xml";
   }

   @Override
   public String getExtension() {
      return ".xml";
   }

   public void writeLyricsPdf(OutputStream os) {
      Document document = new Document();
      try {
         PdfWriter.getInstance(document, os);
         document.open();
         if (null != song.getEnglishName()) {
            Paragraph englishTitle = new Paragraph(song.getEnglishName(),
                  TitleEnglish);
            englishTitle.setAlignment(Paragraph.ALIGN_CENTER);
            document.add(englishTitle);
         }
         if (null != song.getEnglishLyrics()) {
            document.add(new Paragraph("\n"));
            document.add(new Paragraph(song.getEnglishLyrics().replace(
                  Util.DIVIDER, "\n"), FontEnglish));
         }
         document.newPage();
         if (null != song.getChineseName()) {
            Paragraph chineseTitle = new Paragraph(song.getChineseName(),
                  TitleChinese);
            chineseTitle.setAlignment(Paragraph.ALIGN_CENTER);
            document.add(chineseTitle);
         }
         if (null != song.getChineseLyrics()) {
            document.add(new Paragraph("\n"));
            document.add(new Paragraph(song.getChineseLyrics().replace(
                  Util.DIVIDER, "\n"), FontChinese));
         }
         document.close();
      } catch (Exception e) {
         log.info(e.getMessage());
         e.printStackTrace();
      }
   }
}
